import copy
import json
import requests
from tornado.websocket import WebSocketHandler
from sqlalchemy import or_, and_

from models.chat import UserMessage, GroupUser, GroupUserMid
from .base import BaseApiHandler
from settings import UPSTREAM, type_dict

endpoint = 'message/user_message'


class GetUserInfo:
    def get_user_info(self, user_type, token):
        print(user_type)
        if user_type != "group":
            from_user_response = requests.get(
                self._url_join(endpoint, UPSTREAM[user_type]), params={"token": token})
            fromuser = json.loads(from_user_response.content.decode())
            try:
                user_id = fromuser.get("data").get("id")
            except:
                return
            if not user_id:
                return
            from_user = fromuser.get("data")
        else:
            from_user_obj = self.db_session.query(GroupUser).filter(GroupUser.token == token).first()
            if not from_user_obj:
                return
            from_user = {
                "id": from_user_obj.id,
                "name": from_user_obj.group_name,
                "avatar": from_user_obj.group_avatar,
                "token": token,
            }
        return from_user


class ChatWebsocketHandler(BaseApiHandler, WebSocketHandler, GetUserInfo):
    connected_users = dict()

    def check_origin(self, origin):
        return True

    def data_received(self, chunk):
        pass

    # def on_open(self):

    def open(self):

        token = None
        if "token" in self.request.arguments:
            token = self.get_argument('token')

        if not token:
            return None

        self.write_message('connect success administrator! + token:{}'.format(token))
        self.connected_users[token] = self

        self.token = token

        print("has connected {} users".format(len(self.connected_users)))

    # def get_user_info(self, user_type, token):
    #     print(user_type)
    #     if user_type != "group":
    #         from_user_response = requests.get(
    #             self._url_join(endpoint, UPSTREAM[user_type]), params={"token": token})
    #         fromuser = json.loads(from_user_response.content.decode())
    #         from_user = fromuser.get("data")
    #     else:
    #         from_user_obj = self.db_session.query(GroupUser).filter(GroupUser.token == token).first()
    #         from_user = {
    #             "id": from_user_obj.id,
    #             "name": from_user_obj.group_name,
    #             "avatar": from_user_obj.group_avatar,
    #             "token": from_user_obj.token,
    #         }
    #     return from_user

    def on_message(self, message):
        print("recieve" + message)

        token = self.get_argument('token')

        try:
            message = json.loads(message, encoding="utf-8")
        except Exception as e:
            print(e)
            pass
            # self.write(json.dumps({'data': {"message": message}}))

        else:
            msg = message.get("content")
            content_type = message.get("content_type")
            from_type = message.get("from_type")
            to_token = message.get("to_token")
            to_type = message.get("to_type")

            from_user_type = type_dict.get(from_type)
            to_user_type = type_dict.get(to_type)
            from_user = self.get_user_info(from_user_type, token)
            to_user = self.get_user_info(to_user_type, to_token)
            if from_user and to_user:
                self.user(token, from_type, to_type, from_user, to_token, to_user, msg, content_type)
            else:
                # self.write(json.dumps({'data': {"message": "无效用户"}}))
                pass

    def on_close(self):
        token = self.token
        if token in self.connected_users:
            print("断开链接:{}".format(token))
            del self.connected_users[token]
            print("has connected {} users".format(len(self.connected_users)))

    def user(self, token, from_type, to_type, from_user, to_token, to_user, msg, content_type):
        user_message = UserMessage()
        user_message.user_id = from_user.get('id')
        user_message.to_user_id = to_user.get('id')
        user_message.from_type = from_type
        user_message.from_token = token
        user_message.to_token = to_token
        user_message.from_name = from_user.get('name')
        user_message.to_type = to_type
        user_message.to_name = to_user.get('name')
        user_message.has_read = 0
        user_message.content = msg
        user_message.content_type = content_type
        if to_type == 4:
            temp_list = [to_token, ]
        else:
            temp_list = [token, to_token]
        temp_list.sort()
        user_message.ticket = temp_list
        self.db_session.add(user_message)

        self.db_session.commit()

        data = {
            "id": user_message.id,
            "user_id": {
                "id": from_user.get('id'),
                "name": from_user.get('name'),
                "avatar": from_user.get('avatar')
            },
            "from_user_type": from_type,
            "to_user_type": to_type,
            "has_read": 0,
            "created_at": user_message.created_at.strftime("%Y-%m-%d %H:%M:%S"),
            "content": user_message.content,
            "content_type": user_message.content_type,
            "token": token,
            "to_token": to_token,
            "ticket": user_message.ticket,
            "to_user_id": {
                "id": to_user.get('id'),
                "name": to_user.get('name'),
                "avatar": to_user.get('avatar')
            }
        }
        return_data = {'data': data}
        return_data = json.dumps(return_data)
        if to_type == 4:
            group_user_list = self.db_session.query(GroupUserMid).filter(
                GroupUserMid.group_id == int(to_user.get('id'))).all()
            for user in group_user_list:
                to_user_cli = self.connected_users.get(user.token)
                if to_user_cli:
                    to_user_cli.write_message(return_data)
        else:
            self.write_message(return_data)
            to_user_cli = self.connected_users.get(to_token)
            if to_user_cli:
                to_user_cli.write_message(return_data)


class ChatUserHandler(BaseApiHandler):
    def get(self):
        token = self.get_argument('token')

        user_message = self.db_session.query(
            UserMessage
        ).filter(
            or_(UserMessage.from_token == token,
                UserMessage.to_token == token,
                and_(GroupUserMid.token == token,
                     GroupUser.id == GroupUserMid.group_id,
                     UserMessage.to_token == GroupUser.token
                     )
                )
        ).order_by(
            UserMessage.created_at.desc()
        ).all()

        mm = self.db_session.query(UserMessage).group_by(UserMessage.ticket).all()
        print(mm)
        m_list = []
        e_list = []

        for message in user_message:
            print(message.id)
            ticket = copy.copy(message.ticket)
            if ticket not in m_list:
                m_list.append(ticket)
                e_list.append(message)

        return self.return_json({
            'status': 200,
            'message': '',
            'data': {
                'recruits': {
                    'items': [{
                        'id': item.id,
                        'from_name': item.from_name,
                        'from_type': item.from_type,
                        'from_token': item.from_token,
                        'to_name': item.to_name,
                        'to_type': item.to_type,
                        'to_token': item.to_token,
                        'create_at': self.dt2strtime(item.created_at)
                    } for item in e_list]
                }
            }
        })


class ChatHistoryHandler(BaseApiHandler):
    def get(self):
        token = self.get_argument('token')

        query = self.db_session.query(
            UserMessage
        ).filter(
            or_(UserMessage.from_token == token,
                UserMessage.to_token == token,
                and_(GroupUserMid.token == token,
                     GroupUser.id == GroupUserMid.id,
                     UserMessage.to_token == GroupUser.token
                     )
                )
        )

        return self.return_json({
            'status': 200,
            'message': '',
            'data': {
                'recruits': {
                    'items': [{
                        'id': item.id,
                        'from_name': item.from_name,
                        'from_type': item.from_type,
                        'to_name': item.to_name,
                        'to_type': item.to_type,
                        'content': item.content,
                        'created_at': self.dt2strtime(item.created_at)
                    } for item in query]
                }
            }
        })


class ChatIdentHandler(BaseApiHandler):
    def get(self, chat_id):
        the_user_chat = self.db_session.query(
            UserMessage
        ).filter(
            UserMessage.id == chat_id
        ).first()

        user_message = self.db_session.query(
            UserMessage
        ).order_by(UserMessage.created_at.desc()).all()

        m_list = []
        for m in user_message:
            if m.ticket == the_user_chat.ticket:
                m_list.append(m)

        return self.return_json({
            'status': 200,
            'message': '',
            'data': {
                'message_list': {
                    'items': [{
                        'id': item.id,
                        'from_name': item.from_name,
                        'from_type': item.from_type,
                        'to_name': item.to_name,
                        'to_type': item.to_type,
                        'content': item.content,
                        'created_at': self.dt2strtime(item.created_at)
                    } for item in m_list]
                }
            }
        })


class GroupChathandler(BaseApiHandler, GetUserInfo):
    def get(self):
        return self.return_json({
            'status': 200,
            'message': '',
            'data': ""
        })

    def post(self):
        """
        创建群聊
        :return:
        """
        request_data = json.loads(self.request.body.decode())
        group_name = request_data.get("group_name")
        created_user_token = request_data.get("created_user_token")
        created_user_type = request_data.get("created_user_type")
        created_user_type_str = type_dict.get(created_user_type)
        create_user = self.get_user_info(created_user_type_str, created_user_token)
        if not create_user:
            return self.return_json({
                'status': 404,
                'message': '',
                'data': ""
            })
        created_user_id = create_user.get("id")
        user_list = request_data.get("user_list")
        group_user = GroupUser()
        group_user.group_name = group_name
        group_user.created_user_token = created_user_token
        group_user.created_user_type = created_user_type
        group_user.created_user_id = created_user_id
        self.db_session.add(group_user)
        self.db_session.commit()
        for user in user_list:
            user_type = user.get("user_type")
            user_token = user.get("user_token")
            user_type_str = type_dict.get(user_type)
            user_member = self.get_user_info(user_type_str, user_token)
            if not user_member:
                return self.return_json({
                    'status': 404,
                    'message': '',
                    'data': ""
                })
            group_user_mid = GroupUserMid()
            group_user_mid.user_id = user_member.get("id")
            group_user_mid.group_id = group_user.id
            group_user_mid.user_name = user_member.get("name")
            group_user_mid.user_type = user_type
            group_user_mid.token = user_token
            self.db_session.add(group_user_mid)
            self.db_session.commit()
        return self.return_json({
            'status': 200,
            'message': '',
            'data': ""
        })


class Dumphandler(BaseApiHandler):
    def get(self):
        token = self.get_argument('to_token')
        connect_client = ChatWebsocketHandler.connected_users.get(token)
        if connect_client:
            return self.return_json({"code": ''})
        else:
            return self.return_json({"code": "0"})
